import requests
import hashlib
import time
from datetime import datetime, timedelta
from django.utils import timezone
from ..models.wechat_user import WechatUser
import json

class WechatLogic:
    """微信业务逻辑类"""
    
    def __init__(self):
        self.app_id = 'wxbf554b41c5f8f3d1'  # 替换为您的微信AppID
        self.app_secret = '6d3da06a05c2d209002567b8fb50338c'  # 替换为您的微信AppSecret
        self.access_token = None
        self.access_token_expires_at = None

    def login_by_code(self, code):
        """通过code登录"""
        # 请求微信接口获取openid和session_key
        url = 'https://api.weixin.qq.com/sns/jscode2session'
        params = {
            'appid': self.app_id,
            'secret': self.app_secret,
            'js_code': code,
            'grant_type': 'authorization_code'
        }
        
        response = requests.get(url, params=params)
        result = response.json()
        
        if 'errcode' in result:
            raise Exception(f'微信登录失败：{result.get("errmsg")}')
        
        return result.get('openid'), result.get('session_key')

    def login_by_openid(self, openid):
        """通过openid登录"""
        return openid, None

    def generate_token(self, openid):
        """生成用户token"""
        return hashlib.md5(f"{openid}{time.time()}".encode()).hexdigest()

    def get_or_create_user(self, openid, token):
        """获取或创建用户"""
        user, created = WechatUser.objects.get_or_create(
            openid=openid,
            defaults={
                'nickname': '微信用户',
                'avatar': '/media/images/default_avatar.png',
                'gender': 0,
                'token': token,
                'token_expires_at': timezone.now() + timedelta(seconds=1000*60*60*24*30)
            }
        )
        
        # 如果是已存在的用户，更新token
        if not created:
            user.token = token
            user.token_expires_at = timezone.now() + timedelta(seconds=1000*60*60*24*30)
            user.save()
        
        return user

    def get_user_by_token(self, token):
        """通过token获取用户"""
        try:
            user = WechatUser.objects.get(token=token)
            if not user.is_token_valid():
                raise Exception('token已过期')
            return user
        except WechatUser.DoesNotExist:
            raise Exception('无效的token')

    def update_user_info(self, user, data):
        """更新用户信息"""
        if 'nickname' in data:
            user.nickname = data['nickname']
        if 'avatar' in data:
            user.avatar = data['avatar']
        if 'gender' in data:
            user.gender = data['gender']
        if 'country' in data:
            user.country = data['country']
        if 'province' in data:
            user.province = data['province']
        if 'city' in data:
            user.city = data['city']
        
        user.save()
        return user

    def get_access_token(self):
        """获取access_token"""
        # 如果access_token存在且未过期，直接返回
        if self.access_token and self.access_token_expires_at and timezone.now() < self.access_token_expires_at:
            return self.access_token
            
        # 请求微信接口获取access_token
        url = 'https://api.weixin.qq.com/cgi-bin/token'
        params = {
            'grant_type': 'client_credential',
            'appid': self.app_id,
            'secret': self.app_secret
        }
        
        response = requests.get(url, params=params)
        result = response.json()
        
        if 'errcode' in result:
            raise Exception(f'获取access_token失败：{result.get("errmsg")}')
        
        # 更新access_token和过期时间
        self.access_token = result.get('access_token')
        self.access_token_expires_at = timezone.now() + timedelta(seconds=result.get('expires_in', 7200) - 300)  # 提前5分钟过期
        
        return self.access_token

    def send_customer_service_message(self, openid, msg_type, content):
        """发送客服消息
        Args:
            openid: 接收消息的用户openid
            msg_type: 消息类型，支持text/image/link/miniprogrampage
            content: 消息内容，根据msg_type不同而不同
                - text: 字符串，消息内容
                - image: 字符串，图片media_id
                - link: 字典，包含title/description/url/thumb_url
                - miniprogrampage: 字典，包含title/pagepath/thumb_media_id/appid
        """
        access_token = self.get_access_token()
        url = f'https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token={access_token}'
        
        # 构建消息体
        message = {
            'touser': openid,
            'msgtype': msg_type
        }
        
        if msg_type == 'text':
            # 确保content是字符串类型
            if not isinstance(content, str):
                content = str(content)
            message['text'] = {'content': content}
        elif msg_type == 'image':
            message['image'] = {'media_id': content}
        elif msg_type == 'link':
            # 验证链接消息格式
            if not isinstance(content, dict):
                raise Exception('链接消息内容必须是字典格式')
            required_fields = ['title', 'description', 'url', 'thumb_url']
            for field in required_fields:
                if field not in content:
                    raise Exception(f'链接消息缺少必要字段: {field}')
            message['link'] = content
        elif msg_type == 'miniprogrampage':
            message['miniprogrampage'] = content
        else:
            raise Exception('不支持的消息类型')
        
        # 使用json.dumps确保中文正确编码
        json_data = json.dumps(message, ensure_ascii=False)
        headers = {'Content-Type': 'application/json; charset=utf-8'}
        
        response = requests.post(url, data=json_data.encode('utf-8'), headers=headers)
        result = response.json()
        
        if result.get('errcode') != 0:
            raise Exception(f'发送客服消息失败：{result.get("errmsg")}')
        
        return True 